<?php
namespace Core\CoreComponents\DocumentsManager;
use Core;

require_once(COMPONENTS_DIR . 'DocumentsManager/FileSystemHelpers.php');
require_once(COMPONENTS_DIR . 'DocumentsManager/IDocuments.php');
require_once(CONTRACTS_DIR . 'document.entity.php');
/**
* This interface provide all accessible methods on documents module
*
* @method ServiceResponse getDocuments($root, $forceToRefresh, $filter)
* @method ServiceResponse getDocumentsCount($root)
* @method ServiceResponse uploadDocument($tempPath, $dirPath, $filename)
* @method ServiceResponse deleteDocument($path)
* @method ServiceResponse renameDocument($path, $newName, $oldName)
* @method ServiceResponse createTempDocument($sourcePath)
* @method ServiceResponse createFolder($path, $name)
*/
class Documents implements IDocuments
{
	/**
	* @property FileSystemHelpers $FileSystemHelpers
	*/
	private $FileSystemHelpers;

	/**
	 * Default constructor
	 */
	public function __construct()  
    {  
		$this->FileSystemHelpers = new FileSystemHelpers();
    }

	/**
	 * Get all documents from root
	 * 
	 * @param string $root The new value 
	 * @param boolean $forceToRefresh Force to refresh the cache value on the server side
	 * @param string $filter Set a filter on the search pattern
	 *
	 * @return ServiceResponse The response contains all documents found on the provided path with the filter
	 */
    public function getRecursiveDocuments($root, $forceToRefresh, $filter)
	{
		Core\CoreCommons\Logger::Info("Documents - getRecursiveDocuments from $root, $forceToRefresh");
		
		$response = null;
		
		try
		{	
			$root = $this->FileSystemHelpers->RemoveAccent($root);
		
			if(isset($root) == false)
			{
				throw new \Exception("The root is null.");
			}
			
			if(is_dir($root) == false)
			{
				throw new \Exception("The path $root doesn't exist.");
			}
			
			if($forceToRefresh == true)
			{
				$documents = array();
				
				$startScan = microtime(true);
				
				$this->FileSystemHelpers->GetFilesRecursiveToDocuments($root, $documents);
				
				$endScan = microtime(true);
				
				Core\CoreCommons\Logger::Info("Documents - getRecursiveDocuments " . ($endScan-$startScan));
				
				if($filter != null && $filter != "")
				{
					$filteredArray = array();
					
					foreach($documents as $document)
					{
						if (strpos(strtolower($document->Name), strtolower($filter)) !== false) 
						{
							array_push($filteredArray, $document);
						}
					}
					
					$documents = $filteredArray;
				}
				
				//usort($documents, array("Document", "Compare"));
				
				$_SESSION['documentsRepository'] = $documents;
				
				$response = new Core\CoreCommons\ServiceResponse($documents);
			}
			else
			{
				if(isset($_SESSION["documentsRepository"]) == false)
				{
					Core\CoreCommons\Logger::Info("The documents repository is null.");
					
					$response = $this->getRecursiveDocuments($root, true);
				}
				else
				{
					Core\CoreCommons\Logger::Info("The documents repository contains ". count($_SESSION["documentsRepository"]) ." documents.");
					
					$response = new Core\CoreCommons\ServiceResponse($_SESSION["documentsRepository"]);
				}
			}
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Get all documents from root
	 * 
	 * @param string $root The new value 
	 * @param boolean $forceToRefresh Force to refresh the cache value on the server side
	 * @param string $filter Set a filter on the search pattern
	 *
	 * @return ServiceResponse The response contains all documents found on the provided path with the filter
	 */
    public function getDocuments($root, $forceToRefresh, $filter)
	{
		Core\CoreCommons\Logger::Info("Documents - getDocuments from $root, $forceToRefresh");
		
		$response = null;
		
		try
		{	
			$root = $this->FileSystemHelpers->RemoveAccent($root);
		
			if(isset($root) == false)
			{
				throw new \Exception("The root is null.");
			}
			
			if(is_dir($root) == false)
			{
				throw new \Exception("The path $root doesn't exist.");
			}
			
			if($forceToRefresh == true)
			{
				$documents = array();
				
				$startScan = microtime(true);
				
				$this->FileSystemHelpers->GetFilesToDocuments($root, $documents);
				
				$endScan = microtime(true);
				
				Core\CoreCommons\Logger::Info("Documents - getDocuments " . ($endScan-$startScan));
				
				if($filter != null && $filter != "")
				{
					$filteredArray = array();
					
					foreach($documents as $document)
					{
						if (strpos(strtolower($document->Name), strtolower($filter)) !== false) 
						{
							array_push($filteredArray, $document);
						}
					}
					
					$documents = $filteredArray;
				}
				
				//usort($documents, array("Document", "Compare"));
				
				$_SESSION['documentsRepository'] = $documents;
				
				$response = new Core\CoreCommons\ServiceResponse($documents);
			}
			else
			{
				if(isset($_SESSION["documentsRepository"]) == false)
				{
					Core\CoreCommons\Logger::Info("The documents repository is null.");
					
					$response = $this->getDocuments($root, true);
				}
				else
				{
					Core\CoreCommons\Logger::Info("The documents repository contains ". count($_SESSION["documentsRepository"]) ." documents.");
					
					$response = new Core\CoreCommons\ServiceResponse($_SESSION["documentsRepository"]);
				}
			}
		}
		catch (\Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Get the number of documents from root
	 * 
	 * @param string $root The new value 
	 *
	 * @return ServiceResponse The response contains all documents found on the provided path
	 */
    public function getDocumentsCount($root)
	{
		Core\CoreCommons\Logger::Info("Documents - getDocumentsCount from $root");
		
		$response = null;
		
		try
		{	
			$root = $this->FileSystemHelpers->RemoveAccent($root);
		
			$number = $this->FileSystemHelpers->GetCountFiles($root);
			
			$response = new Core\CoreCommons\ServiceResponse($number);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Upload document
	 * 
	 * @param string $tempPath The temp path use to upload the document
	 * @param string $dirPath The target directory to copy the file
	 * @param string $filename The file name to copy
	 *
	 * @return ServiceResponse The response contains the uploaded document
	 */
    public function uploadDocument($tempPath, $dirPath, $filename)
	{
		Core\CoreCommons\Logger::Info("Documents - uploadDocument to $tempPath, $dirPath, $filename");
		
		$response = null;
		
		try
		{	
			$tempPath = $this->FileSystemHelpers->RemoveAccent($tempPath);
			$dirPath = $this->FileSystemHelpers->RemoveAccent($dirPath);
			$filename = $this->FileSystemHelpers->RemoveAccent($filename);
		
			$result = $this->FileSystemHelpers->Upload($tempPath, $dirPath, $filename);
			
			$response = new Core\CoreCommons\ServiceResponse($result);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Delete a document from his path
	 * 
	 * @param string $path The path use to delete the document
	 *
	 * @return ServiceResponse The response contains the deleted document
	 */
    public function deleteDocument($path)
	{
		Core\CoreCommons\Logger::Info("Documents - deleteDocument from $path");
		
		$response = null;
		
		try
		{	
			$path = $this->FileSystemHelpers->RemoveAccent($path);
		
			$result = $this->FileSystemHelpers->Delete($path);
			
			$response = new Core\CoreCommons\ServiceResponse($result);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Rename document
	 * 
	 * @param string $path The document path to rename
	 * @param string $newName The new document name
	 * @param string $oldName The old document name
	 *
	 * @return ServiceResponse The response contains the renamed document
	 */
    public function renameDocument($path, $newName, $oldName)
	{
		Core\CoreCommons\Logger::Info("Documents - renameDocument $path, $newName, $oldName");
		
		$response = null;
		
		try
		{	
			$path = $this->FileSystemHelpers->RemoveAccent($path);
			$newName = $this->FileSystemHelpers->RemoveAccent($newName);
			$oldName = $this->FileSystemHelpers->RemoveAccent($oldName);
		
			$result = $this->FileSystemHelpers->Rename($path, $newName, $oldName);
			
			$response = new Core\CoreCommons\ServiceResponse($result);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Create a temporary file to download
	 * 
	 * @param string $sourcePath The path to the targeted document 
	 * 
	 * @return ServiceResponse The response contains the new temporary document 
	 */
    public function createTempDocument($sourcePath)
	{
		Core\CoreCommons\Logger::Info("Documents - createTempDocument $sourcePath");
		
		$response = null;
		
		try
		{	
			$sourcePath = $this->FileSystemHelpers->RemoveAccent($sourcePath);
		
			$parameters = Core\CoreCommons\Parameters::Instance();
			$rootPath = $parameters::$Keys["TempPath"];
			$rootPath = $this->FileSystemHelpers->RemoveAccent($rootPath);
			
			$filename = basename($sourcePath);
			
			$targetFolder = $rootPath . DIRECTORY_SEPARATOR . $filename;
			
			Core\CoreCommons\Logger::Info("createTempDocument => $targetFolder");
		
			$result = $this->FileSystemHelpers->Copy($sourcePath, $targetFolder);
			
			$response = new Core\CoreCommons\ServiceResponse($result);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Create a temporary file to download
	 * 
	 * @param string $sourcePath The path to the targeted document 
	 * 
	 * @return ServiceResponse The response contains the new temporary document 
	 */
    public function createTempDocumentFromBinary($fileName, $fileExtension, $binaryDataFile)
	{
		Core\CoreCommons\Logger::Info("Documents - createTempDocumentFromBinary $fileName,  $fileExtension");
		
		$response = null;
		
		try
		{	
			$binary = base64_decode($binaryDataFile);
			
			$newFileFullname = sprintf("%s/%s", __dir__ . '/Temp/', $fileName);
			
			//Check if file already exist
			if(file_exists($newFileFullname))
			{
				//if file alread y exist delete it
				unlink($newFileFullname);
			}
			else
			{
				// else create file
				$fp = fopen($newFileFullname, '');
				fclose($fp);
			}

			file_put_contents($newFileFullname, $binary);
			
			$response = new Core\CoreCommons\ServiceResponse($newFileFullname);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
	
	/**
	 * Create a folder
	 * 
	 * @param string $path The path to the targeted repository 
	 * @param string $name The name of the targeted folder to create
	 *
	 * @return ServiceResponse The response contains the created folder
	 */
    public function createFolder($path, $name)
	{
		Core\CoreCommons\Logger::Info("Documents - createFolder $path, $name");
		
		$response = null;
		
		try
		{	
			$path = $this->FileSystemHelpers->RemoveAccent($path);
			$name = $this->FileSystemHelpers->RemoveAccent($name);
		
			$targetFolder = $path . DIRECTORY_SEPARATOR . $name;
			
			Core\CoreCommons\Logger::Info("createFolder => $targetFolder");
		
			$result = $this->FileSystemHelpers->CreateDirectory($targetFolder);
			
			$response = new Core\CoreCommons\ServiceResponse($result);
		}
		catch (Exception $ex) 
		{
			$response = Core\CoreCommons\ServiceResponse::CreateError($ex);
		}
		
		return $response;
	}
}

?> 